<template>
  <Layout>
    <template #main-content>
      <div
        class="h-screen flex flex-col overflow-y-auto items-center justify-center flex-1"
        ref="chatContainer"
      >
        <!-- 聊天记录区域 -->
        <div class="flex-1 max-w-3xl mx-auto pb-24 pt-4 px-4 w-full">
          <!-- 遍历聊天记录 -->
          <template v-for="(chat, index) in chatList" :key="index">
            <!-- 用户提问消息 靠右 -->
            <div v-if="chat.role === 'user'" class="flex justify-end mb-4">
              <div class="quesiton-container">
                <p>{{ chat.content }}</p>
              </div>
            </div>

            <!-- 大模型回答 靠左 -->
            <div class="flex mb-4" v-else>
              <!-- 头像 -->
              <div class="flex-shrink-0 mr-3">
                <div
                  class="w-8 h-8 rounded-full flex items-center justify-center border border-gray-200"
                >
                  <SvgIcon name="deepseek-logo" customSvgCss="w-5 h-5" />
                </div>
              </div>
              <!-- 回复的内容 -->
              <div class="p-1 max-w-[90%] mb-2">
                <LoadingDots v-if="chat.loading" />
                <StreamMarkdownRender :content="chat.content" />
              </div>
            </div>
          </template>
        </div>

        <!-- 提问框区域 -->
        <ChatInputBox
          v-model="userMessage"
          containerClass="sticky max-w-3xl mx-auto bg-white bottom-10 left-0 w-full"
          @sendMessage="sendMsg"
        />
      </div>
    </template>
  </Layout>
</template>

<script setup lang="ts">
import { ref, nextTick, onMounted, onBeforeUnmount } from 'vue'
import SvgIcon from '@/components/SvgIcon.vue'
import StreamMarkdownRender from '@/components/StreamMarkdownRender.vue'
import ChatInputBox from '@/components/ChatInputBox.vue'
import Layout from '@/layouts/Layout.vue'
import { useRoute } from 'vue-router'
import { useChatStore } from '@/stores/chatStore'
import { fetchEventSource } from '@microsoft/fetch-event-source'
import LoadingDots from '@/components/LoadingDots.vue'
import { getHistoryMsg } from '@/api/request'

const route = useRoute()

const chatStore = useChatStore()

console.log('首页传递过来的消息：', history.state?.firstMessage)

console.log('route: ', route.params)

// 用户输入消息
const userMessage = ref(history.state?.firstMessage || '')
const chatId = ref(route.params.chatId || null)
// textarea自适应高度引用
const textareaRef = ref(null)
const chatContainer = ref(null)
// 聊天记录（给一个默认的问候语）
const chatList = ref([
  {
    role: 'assistant',
    content:
      '您好，我是智能AI小助手小满哥！✨ 我可以帮你解答各种问题，无论是学习、工作，还是日常生活中的小困惑，都可以找我聊聊。有什么我可以帮你的吗？😊',
    loading: false,
  },
])
// 历史消息分页
const currentPage = ref(1)
const pageSize = ref(10)
const hasMorePage = ref(true)
const isLoadingMsg = ref(false)

const sendMsg = async (payload) => {
  console.log('payload: ', payload)

  // 发送消息不能为空
  if (!userMessage.value.trim()) return

  console.log('选中的模型：', payload.selectedModel)
  console.log('是否联网搜索：', payload.isNetWork)

  // 将用户信息添加到chatList聊天列表中
  const userMsg = userMessage.value.trim()
  chatList.value.push({
    role: 'user',
    content: userMsg,
    loading: true,
  })

  // 点击发送按钮后，清空输入框
  userMessage.value = ''
  // 将输入框的高度重置
  if (textareaRef.value) {
    textareaRef.value.style.height = 'auto' // 重置高度
  }
  // 添加一个占位的回复消息
  chatList.value.push({
    role: 'assistant',
    content: '',
    loading: true,
  })

  try {
    const reqBody = {
      message: userMsg,
      chatId: chatId.value,
      modelName: payload.selectedModel?.name,
      networkSearch: payload.isNetWork,
    }

    console.log('请求体: ', reqBody)

    // 响应的内容
    let responseText = ''
    const lastMessage = chatList.value[chatList.value.length - 1]

    const controller = new AbortController()
    const signal = controller.signal

    fetchEventSource('http://localhost:8080/api/man/chat/completion', {
      method: 'POST',
      signal: signal,
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(reqBody),
      onmessage(msg) {
        if (msg.event === '') {
          if (lastMessage.loading) {
            lastMessage.loading = false
          }
          const parseJson = JSON.parse(msg.data)
          responseText += parseJson.content

          chatList.value[chatList.value.length - 1].content = responseText

          scrollToBottom()
        } else if (msg.event === 'close') {
          console.log('SSE连接关闭事件收到，关闭连接')
          controller.abort()
        }
      },
      onerror(err) {
        throw err
      },
    })
  } catch (error) {
    console.log('发送消息错误: ', error)
    const lastMessage = chatList.value[chatList.value.length - 1]
    lastMessage.content = '抱歉，请求出错了，请稍后再试。'
    lastMessage.loading = false
    scrollToBottom()
  }
}

const loadHistoryMsg = async () => {
  getHistoryMsg({ current: currentPage.value, size: pageSize.value, chatId: chatId.value })
    .then((res) => {
      isLoadingMsg.value = false
      if (res.data.success) {
        const historyMsg = res.data.data

        // 判断是否还有下一页
        hasMorePage.value = res.data.pages > currentPage.value

        if (historyMsg && historyMsg.length > 0) {
          chatList.value = [...historyMsg, ...chatList.value]

          if (currentPage.value === 1) {
            scrollToBottom()
          }
        }
      }

      //确保加载历史消息时，自动滚动到底部（仅第一页）
      if (currentPage.value === 1) {
        // 滚动到底部
        scrollToBottom()
      }
    })
    .catch((err) => {
      console.error('加载历史消息失败: ', err)
      isLoadingMsg.value = false
    })
}

onBeforeUnmount(() => {
  if (chatContainer.value) {
    chatContainer.value.removeEventListener('scroll', handleScroll)
  }
})

onMounted(() => {
  // 加载历史聊天记录
  loadHistoryMsg()

  if (chatContainer.value) {
    chatContainer.value.addEventListener('scroll', handleScroll)
  }

  const firstMessage = history.state?.firstMessage
  if (firstMessage) {
    userMessage.value = firstMessage
    sendMsg({
      selectedModel: chatStore.selectedModel,
      isNetWork: chatStore.isNetWork,
    })

    if (history.replaceState) {
      const newState = { ...history.state }
      delete newState.firstMessage
      history.replaceState(newState, document.title)
    }
  }
})

// 滚动到底部
const scrollToBottom = async () => {
  // 等待Vue.js完成dom更新
  await nextTick()
  // 若容器存在
  if (chatContainer.value) {
    // 将容器的滚动条位置设置到最底部
    const container = chatContainer.value as HTMLElement
    container.scrollTop = container.scrollHeight
  }
}

const handleScroll = () => {
  if (chatContainer.value) {
    // 到滚动区域顶部的距离
    const scrollTop = chatContainer.value.scrollTop
    // 滚动区域的完整高度
    const scrollHeight = chatContainer.value.scrollHeight

    console.log('====== 滚动事件记录 ======')
    console.log('scrollTop: ', scrollTop)
    console.log('scrolleHeight: ', scrollHeight)

    if (scrollTop < 50 && hasMorePage && !isLoadingMsg.value) {
      console.log('====== 触发加载更多历史消息 ======')
      loadMoreHistoryMsg()
    }
  }
}

const loadMoreHistoryMsg = async () => {
  if (!hasMorePage.value) {
    console.log('====== 没有更多历史消息 ======')
    return
  }
  if (isLoadingMsg.value) {
    console.log('====== 正在加载中 ======')
    return
  }

  isLoadingMsg.value = true

  const nextPage = currentPage.value + 1

  const currentTemp = currentPage.value

  currentPage.value = nextPage

  try {
    await loadHistoryMsg()
  } catch (err) {
    currentPage.value = currentTemp
    console.error(err)
  }
}
</script>

<style scoped>
.quesiton-container {
  font-size: 16px;
  line-height: 28px;
  color: #262626;
  padding: calc((44px - 28px) / 2) 20px;
  box-sizing: border-box;
  white-space: pre-wrap;
  word-break: break-word;
  background-color: #eff6ff;
  border-radius: 14px;
  max-width: calc(100% - 48px);
  position: relative;
}
.overflow-y-auto {
  scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
}
</style>
